<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>极简贪吃蛇</title>
</head>
<style>
    body {
        line-height: 1;
    }
</style>
<script>
    var 向, 欲向 = "右", 帧长 = 200, 头行 = 7, 头列 = 7, 蛇长 = 4, 图长 = 16, 头序, 食序, 记头 = "🐲", 记碰 = "💥", 记身 = { 上: "⏫", 下: "⏬", 左: "⏪", 右: "⏩" }, 记食 = "🥜", 记空 = "⬜", 图 = Array(图长 ** 2).fill(记空), 示, 始 = 1
    var 戏 = setInterval(() => {
        头行 += { 上: 图长 - 1, 下: 1 }[欲向] ?? 0 // 移头
        头列 += { 左: 图长 - 1, 右: 1 }[欲向] ?? 0
        头行 %= 图长
        头列 %= 图长
        头序 = 头行 * 图长 + 头列
        let 头格 = 图[头序], 碰 = (头格.记身 && 头格.寿 > 1), 吞 = (头格 == 记食 || 始)
        图 = 图.map(格 => { // 记身
            if (格 == 记头) 格 = { 记身: 记身[欲向], 寿: 蛇长 - 1 };
            if (!吞) 格.寿 -= 1;
            if (格.寿 < 1) 格 = 记空 // 记空
            return 格
        })
        if (吞) { // 记食
            始 = 0
            蛇长 += 1
            do { 食序 = Date.now() % 图长 ** 2 } while (图[食序] != 记空) // 新食，必在空地
            // do { 食序 = Math.floor(Math.random() * 图长 ** 2) } while (图[食序] != 记空) // 新食，必在空地
            图[食序] = 记食
        }
        图[头序] = 碰 ? 记碰 : 记头 // 记头、记碰
        if (碰) clearInterval(戏) // 碰则止
        向 = 欲向
        示 = ""
        图.map((格, 序) => {
            if (序 % 图长 < 1) 示 += "<br>"
            示 += 格.记身 ?? 格
        })
        document.body.innerHTML = 示
    }, 帧长)
    document.onkeydown = e => {
        let 键 = { U: "上", D: "下", L: "左", R: "右" }[e.key[5]] ?? 欲向 // 只读方向键
        if (键 != { 上: "下", 下: "上", 左: "右", 右: "左" }[向]) 欲向 = 键 // 不可回头
    }
</script>
</html>